package com.parking.mgr.useraccount.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.parking.mgr.common.constant.CommonConstant;
import com.parking.mgr.common.enums.AuthCodeNotifyWayEnums;
import com.parking.mgr.common.enums.AuthCodeResultStatusEnums;
import com.parking.mgr.common.enums.AuthCodeStateEnums;
import com.parking.mgr.common.exception.ServiceException;
import com.parking.mgr.common.exception.enums.AuthExceptionEnum;
import com.parking.mgr.common.exception.enums.CommonExceptionEnum;
import com.parking.mgr.common.pojo.auth.CheckCode;
import com.parking.mgr.common.util.IdUtils;
import com.parking.mgr.common.util.TimestampUtil;
import com.parking.mgr.useraccount.facede.LoginServiceFacede;
import com.parking.mgr.useraccount.model.entity.BasicAuthCodeEntity;
import com.parking.mgr.useraccount.model.mapper.BasicAuthCodeMapper;
import com.parking.mgr.useraccount.service.AuthCodeService;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 * @ClassName AuthCodeServiceImpl
 * @Description 基础验证码服务类
 * @author: zhijianpu
 * @Date: 2023/6/14
 */
@Log4j2
@Service
public class AuthCodeServiceImpl extends ServiceImpl<BasicAuthCodeMapper, BasicAuthCodeEntity> implements AuthCodeService {


    @Resource
    private LoginServiceFacede loginServiceFacede;

    @Resource
    private BasicAuthCodeMapper basicAuthCodeMapper;

    @Override
    public void identifyImageCode(HttpServletRequest request, HttpServletResponse response, String eventCode, String clientId) throws IOException {
//        // 创建验证码文本
//        String capText = defaultKaptcha.createText();
//        // 创建验证码图片
//        BufferedImage image = defaultKaptcha.createImage(capText);
//        //String clientId = request.getHeader(CommonConstant.CLIENT_ID);
//
//        log.info("保存验证码");
//        // 设置验证码实体属性
//        String authCodeId = IdUtils.getId();
//        BasicAuthCodeEntity basicAuthCodeEntity = new BasicAuthCodeEntity();
//        basicAuthCodeEntity.setId(authCodeId);
//        basicAuthCodeEntity.setFEventCode(eventCode);
//        basicAuthCodeEntity.setFClientId(clientId);
//
//        basicAuthCodeEntity.setFAuthCode(capText);
//        basicAuthCodeEntity.setFUserAgent(ServletUtil.getHeaderIgnoreCase(request, CommonConstant.USER_AGENT));
//        basicAuthCodeEntity.setFAuthState(AuthCodeStateEnums.AUTH_STATE_UNVERIFIED.getCode());
//        basicAuthCodeEntity.setFNotifyWay(AuthCodeNotifyWayEnums.NOT_WAY_IMAGE.getCode());
//
//        // 保存验证码
//        this.save(basicAuthCodeEntity);
//
//        // 将验证码文本放进 Session 中
//        CheckCode code = new CheckCode(capText);
//        request.getSession().setAttribute(CommonConstant.KAPTCHA_SESSION_KEY, code);
//
//        // 将验证码图片返回，禁止验证码图片缓存
//        response.setHeader("Cache-Control", "no-store");
//        response.setHeader("Pragma", "no-cache");
//        response.setDateHeader("Expires", 0);
//        response.setContentType("image/jpeg");
//        response.setHeader("id", authCodeId);
//        ImageIO.write(image, "jpg", response.getOutputStream());

    }

    @Override
    public String getAuthCodeById(String id) {
        log.info("根据ID获取验证码");
        BasicAuthCodeEntity authCodeEntity = this.getById(id);
        if (ObjectUtil.isNull(authCodeEntity)) {
            throw new ServiceException(AuthExceptionEnum.VALID_CODE_INVALID.getMessage());
        }

        return authCodeEntity.getFAuthCode();
    }

    @Override
    public BasicAuthCodeEntity getAuthCodeEntityByClientId(String clientId) {
        log.info("通过clientId获取验证码");
        LambdaQueryWrapper<BasicAuthCodeEntity> queryWrapper = new LambdaQueryWrapper<BasicAuthCodeEntity>()
                .eq(BasicAuthCodeEntity::getFClientId, clientId)
                .eq(BasicAuthCodeEntity::getFEventCode, CommonConstant.EVENT_CODE_LOGIN)
                .orderByDesc(BasicAuthCodeEntity::getFInsertTimeMillis)
                .last("limit 1");

        BasicAuthCodeEntity basicAuthCodeEntity = basicAuthCodeMapper.selectOne(queryWrapper);
        if (ObjectUtil.isNull(basicAuthCodeEntity)) {
            throw new ServiceException(CommonExceptionEnum.DATA_NOT_EXIST.getMessage());
        }

        return basicAuthCodeEntity;
    }

    @Override
    public void updateAuthCodeByAuthFail(String id, String passportId, String clientId) {
        log.info("验证码校验失败，更新验证码状态和验证结果");
        BasicAuthCodeEntity authCodeEntity = this.getById(id);
        if (ObjectUtil.isNull(authCodeEntity)) {
            throw new ServiceException(AuthExceptionEnum.VALID_CODE_INVALID.getMessage());
        }

        // 设置验证码属性
        authCodeEntity.setFkUserPassportId(passportId);
        authCodeEntity.setFClientId(clientId);
        authCodeEntity.setFAuthResult(AuthCodeResultStatusEnums.AUTH_RESULT_FAIL.getCode());

        this.updateById(authCodeEntity);
    }

    @Override
    @Transactional
    public void updateAuthCodeByAuthSuccess(String id, String passportId, String clientId, String loginToken) {
        log.info("验证码校验成功，更新验证码状态和验证结果");
        BasicAuthCodeEntity authCodeEntity = this.getById(id);
        if (ObjectUtil.isNull(authCodeEntity)) {
            throw new ServiceException(AuthExceptionEnum.VALID_CODE_INVALID.getMessage());
        }

        // 设置验证码属性
        authCodeEntity.setFkUserPassportId(passportId);
        authCodeEntity.setFClientId(clientId);
        authCodeEntity.setFAuthResult(AuthCodeResultStatusEnums.AUTH_RESULT_SUCCESS.getCode());
        authCodeEntity.setFLoginToken(loginToken);

        authCodeEntity.setFCreateTimeMillis(TimestampUtil.createTimestamp());
        authCodeEntity.setFCreateTimeMillis(TimestampUtil.extensionDays());

        //更新验证码属性
        this.updateById(authCodeEntity);
        log.info("验证更新完成后，需要删除数据，并同步更新更新到历史表");
        //更新完成后，删除数据
        this.removeById(authCodeEntity.getId());
    }

}
